package com.keyroy.game.puzzle_rpg.models.render;

import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;

import com.keyroy.game.puzzle_rpg.models.environment.Battle;
import com.keyroy.game.puzzle_rpg.models.interfaces.SWTDrawable;
import com.keyroy.game.puzzle_rpg.models.puzzle.Result;
import com.keyroy.game.puzzle_rpg.models.role.Role;

public class BattleRender extends SWTDrawable {
	private static final int MAP_BACKGROUND = 0;
	private static final int LT_BACKGROUND = 1;
	private static final int RB_BACKGROUND = 2;

	private Battle battle;
	private Rectangle mapPart;
	private Rectangle alliesPart;
	private Rectangle enemiesPart;
	private Object[] images;
	private boolean isHorizontal;

	private TipsRender tipsRender;
	private PuzzleMapRender puzzleMapRender;
	private List<RoleRender> allyRenders = new ArrayList<RoleRender>();
	private List<RoleRender> enemyRenders = new ArrayList<RoleRender>();

	public BattleRender(Battle battle) {
		this.battle = battle;
		init();
	}

	public boolean inMapRect(Point out) {
		return mapPart.contains(out);
	}

	public void toMapRect(int px, int py, Point out) {
		out.x = px - mapPart.x;
		out.y = py - mapPart.y;
	}

	@Override
	public void onDraw() {
		{ // draw allies
			translate(alliesPart.x, alliesPart.y);
			if (images != null && images[LT_BACKGROUND] != null) {
				drawImage(images[LT_BACKGROUND], 0, 0);
			}

			for (int i = 0; i < allyRenders.size(); i++) {
				int x, y;
				if (isHorizontal) {
					x = 0;
					y = i * mapPart.height / allyRenders.size();
				} else {
					x = i * mapPart.width / allyRenders.size();
					y = 0;
				}

				translate(x, y);
				allyRenders.get(i).onDraw();
				translate(-x, -y);
			}
			translate(-alliesPart.x, -alliesPart.y);
		}

		{ // draw enemies
			translate(enemiesPart.x, enemiesPart.y);

			if (images != null && images[RB_BACKGROUND] != null) {
				drawImage(images[RB_BACKGROUND], 0, 0);
			}

			for (int i = 0; i < enemyRenders.size(); i++) {
				int x, y;
				if (isHorizontal) {
					x = 0;
					y = i * mapPart.height / enemyRenders.size();
				} else {
					x = i * mapPart.width / enemyRenders.size();
					y = 0;
				}

				translate(x, y);
				enemyRenders.get(i).onDraw();
				translate(-x, -y);
			}
			translate(-enemiesPart.x, -enemiesPart.y);
		}

		{ // draw puzzle map
			translate(mapPart.x, mapPart.y);

			if (images != null && images[MAP_BACKGROUND] != null) {
				drawImage(images[MAP_BACKGROUND], 0, 0);
			}

			puzzleMapRender.onDraw();
			tipsRender.onDraw();
			translate(-mapPart.x, -mapPart.y);
		}

	}

	private final void init() {
		initLocation();
		initRender();
	}

	private final void initLocation() {
		if (battle != null) {
			mapPart = new Rectangle();
			alliesPart = new Rectangle();
			enemiesPart = new Rectangle();

			if (battle.battleScene == null) {
				int width = (854 - battle.getPuzzleMap().getWidth()) / 2;
				int height = 480;
				alliesPart.setBounds(0, 0, width, height);
				mapPart.setBounds(width, 0, battle.getPuzzleMap().getWidth(), height);
				enemiesPart.setBounds(mapPart.x + mapPart.width, 0, width, height);
				isHorizontal = true;
			} else {
				images = new Object[3];
				images[MAP_BACKGROUND] = getImage(battle.battleScene.gridBackGround);
				images[LT_BACKGROUND] = getImage(battle.battleScene.leftTop);
				images[RB_BACKGROUND] = getImage(battle.battleScene.rightBottom);

				if (images[MAP_BACKGROUND] != null) {
					int iw = imageWidth(images[MAP_BACKGROUND]);
					int ih = imageHeight(images[MAP_BACKGROUND]);
					mapPart.width = iw;
					mapPart.height = ih;
				}
				if (battle.battleScene.isHorizontal()) { // horzontal
					int tWidth = Math.max(mapPart.width, battle.getPuzzleMap().getWidth());
					int width = 854 - tWidth / 2;
					int height = 480;
					alliesPart.setBounds(0, 0, width, height);
					mapPart.setBounds(width, 0, tWidth, height);
					enemiesPart.setBounds(mapPart.x + mapPart.width, 0, width, height);
					isHorizontal = true;

				} else { // vertical
					int tHeight = Math.max(mapPart.height, battle.getPuzzleMap().getHeight());
					int width = 480;
					int height = (854 - tHeight) / 2;
					alliesPart.setBounds(0, 0, width, height);
					mapPart.setBounds(0, height, width, tHeight);
					enemiesPart.setBounds(0, mapPart.y + mapPart.height, width, height);
				}
			}
		}
	}

	private final void initRender() {
		if (battle != null) {
			tipsRender = new TipsRender(battle.getPuzzleMap());
			puzzleMapRender = new PuzzleMapRender(battle.getPuzzleMap());
			{ // allies
				List<Role> allies = battle.getAllies();

				int width = 0;
				int height = 0;
				if (isHorizontal) {
					width = alliesPart.width;
					height = alliesPart.height / allies.size();
				} else {
					width = alliesPart.width / allies.size();
					height = alliesPart.height;
				}

				for (int i = 0; i < allies.size(); i++) {
					allyRenders.add(new RoleRender(allies.get(i), width, height));
				}
			}

			{ // enemies
				List<Role> enemies = battle.getEnemies();

				int width = 0;
				int height = 0;
				if (isHorizontal) {
					width = alliesPart.width;
					height = alliesPart.height / enemies.size();
				} else {
					width = alliesPart.width / enemies.size();
					height = alliesPart.height;
				}

				for (int i = 0; i < enemies.size(); i++) {
					enemyRenders.add(new RoleRender(enemies.get(i), width, height));
				}
			}

		}
	}

	public void tips() {
		List<Result> results = battle.getPuzzleMap().tips();
		tipsRender.setResults(results);
	}

	public void cancelTips() {
		tipsRender.setResults(null);
	}
}
